package tool;

import model.ApiConfigDataModel;
import model.NeedReplaceStringModel;

import javax.xml.crypto.Data;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by yangxianming on 2015-06-10.
 */
public class DataReplace {

    private static NeedReplaceStringModel obgReplace(ApiConfigDataModel acdm, String  str){
        NeedReplaceStringModel nrsd = new NeedReplaceStringModel(str, false);
        return nrsd;
    }

//    提供给外部调用
    public static String replace(ApiConfigDataModel acdm, String str){
        return innerReplace(acdm, str).string;
    }

//    将${开头的字符用acdm中的配置替换
    private static NeedReplaceStringModel checkDollar(ApiConfigDataModel acdm, String str){
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        if (acdm.config.containsKey(nrsd.string)){
            nrsd.string = acdm.config.get(nrsd.string);
            nrsd.hasReplaced = true;
            return nrsd;
        }else {
            nrsd.hasReplaced = false;
            return nrsd;
        }
    }

//    将$sql{开头的字符用acdm中的配置替换
    private static NeedReplaceStringModel checkSql(ApiConfigDataModel acdm, String str){
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        Statement statement = acdm.statement;
        try {
            ResultSet resultSet = statement.executeQuery(nrsd.string);
            while (resultSet.next()){   //暂时就支持查一个数据出来
                nrsd.string = resultSet.getString(1);
                if (nrsd.string == null)  //如果是null那就给个""值
                    nrsd.string = "";
                break;
            }
            nrsd.hasReplaced = true;
        }catch (SQLException e){
            e.printStackTrace();
        }
//        如果查出来是空值,说明可能语句错误返回查询失败的标记
        if  (nrsd.string.equals(""))
            nrsd.hasReplaced = false;
        return nrsd;
    }

//    将$random{开头的字符做对应的随机值处理
//    暂时先支持
//    9 就是说明0-9中随机
//    1,2,3 中随机
//    1-10 范围随机
    private static NeedReplaceStringModel checkRandom(ApiConfigDataModel acdm, String str){
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        String result = "";
        Random random = new Random();
        if (str.contains("-")){
            String[] fromTo = {"", ""};
            fromTo = str.split("-");
            fromTo[0] = fromTo[0].trim();
            fromTo[1] = fromTo[1].trim();
            result = String.valueOf(Integer.valueOf(fromTo[0]) + random.nextInt(Integer.valueOf(fromTo[1]) + 1));
            nrsd.hasReplaced = true;
        }
        else if (str.contains(",")){
            String[] randomArray = new String[]{};
            randomArray = str.split(",");
            for (String string:randomArray)
                string = string.trim();
            result = randomArray[random.nextInt(randomArray.length)];
            nrsd.hasReplaced = true;
        }else {
            result = String.valueOf(random.nextInt(Integer.valueOf(str)) + 1);
            nrsd.hasReplaced = true;
        }

        nrsd.string = result;
        return nrsd;
    }

//    替换longtime
    private static NeedReplaceStringModel checkLongTime(ApiConfigDataModel acdm, String str){
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        Date data = new Date();
        SimpleDateFormat formatter = null;
        if (nrsd.string.equals("")){     //这个默认反悔当前的13位时间戳
            Long longtime = data.getTime();

//            获取10位时间戳，以后如果不用就把一下两行注释掉
            String longtion10 = longtime.toString();
            nrsd.string = longtion10.substring(0, 10);

//            nrsd.string = longtime.toString();
            nrsd.hasReplaced = true;
            return nrsd;
        }
        if (str.contains("-") && !str.contains(":")){
            formatter = new SimpleDateFormat("yyyy-MM-dd");
        }
        if (!str.contains("-") && str.contains(":")){
            formatter = new SimpleDateFormat("HH:mm:ss");
        }
        if (str.contains("-") && str.contains(":")){
            formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        if (formatter == null){
            System.out.println("time format exception");
            return nrsd;
        }
        Long tempTime = 0l;
        try {
            tempTime = formatter.parse(str).getTime();
        }catch (Exception e){
            e.printStackTrace();
        }
        nrsd.string = tempTime.toString();
        nrsd.hasReplaced = true;
        return nrsd;
    }

//    对其中的字符串做UrlEncode
    private static NeedReplaceStringModel checkUrlEncode(ApiConfigDataModel acdm, String str) {
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        try {
            nrsd.string = URLEncoder.encode(nrsd.string, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

        nrsd.hasReplaced = true;
        return nrsd;
    }

//    对其中的字符串做UrlDecode
    private static NeedReplaceStringModel checkUrlDecode(ApiConfigDataModel acdm, String str) {
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        try {
            nrsd.string = URLDecoder.decode(nrsd.string, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        nrsd.hasReplaced = true;
        return nrsd;
    }

    public static NeedReplaceStringModel innerReplace(ApiConfigDataModel acdm, String str){
        String[] dollarList = {"${", "$sql{", "$random{", "$longtime{", "$urlEncode{", "$urlDecode{"};
        str = str.trim();
        NeedReplaceStringModel nrsd = obgReplace(acdm, str);
        String tempString = "";
        String needReplaceString = "";
        boolean findDollar = false;  //表示如果全部被替换完,就结束循环
        if (str.contains("$")){     //如果有$符号,说明可能有需要替换的,否则就直接跳过
            for (String oneDollar:dollarList){  //这里就确认是不是需要替换,如果有就跳出
                if (str.contains(oneDollar)){
                    findDollar = true;
                    break;
                }
            }
        }
//        if (str.contains("${") || str.contains("$sql{") || str.contains("$random{"))
//            findDollar = true;
//        如果替换失败 .就break出循环
        while (findDollar){
            int lastDollarIndex = str.lastIndexOf("$");
            int startIndex = 0;     //被替换的字符串的开头下标
            int lastIndex = 0;      //结尾下标
//            根据不同的$标记给出下标的长度
            for (String oneDollar:dollarList){
                int oneDollarLength = oneDollar.length();
                if ((lastDollarIndex + oneDollarLength - lastDollarIndex) > str.length())   //防止在substring时数组过长
                    continue;
                if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals(oneDollar)){
                    startIndex = lastDollarIndex + oneDollarLength;
                    break;
                }
            }

//            获取最靠近他的一个}符号的下标值
            tempString = str.substring(startIndex, str.length());
            lastIndex = tempString.indexOf("}");
            needReplaceString = tempString.substring(0, lastIndex);
            lastIndex = startIndex + lastIndex;

//            这里开始替换目标串
//            如果替换失败或者查询失败那就直接break循环
            for (String oneDollar:dollarList){
                int oneDollarLength = oneDollar.length();
//              这里添加替换调用方法.
                if (str.length() >= oneDollarLength){   //防止substring数组益处
                    if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals("${")){
                        nrsd = checkDollar(acdm, needReplaceString);
                        break;
                    }
                }
                if (str.length() >= oneDollarLength){
                    if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals("$sql{")){
                        nrsd = checkSql(acdm, needReplaceString);
                        break;
                    }
                }
                if (str.length() >= oneDollarLength){
                    if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals("$random{")){
                        nrsd = checkRandom(acdm, needReplaceString);
                        break;
                    }
                }
                if (str.length() >= oneDollarLength){
                    if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals("$longtime{")){
                        nrsd = checkLongTime(acdm, needReplaceString);
                        break;
                    }
                }
                if (str.length() >= oneDollarLength){
                    if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals("$urlEncode{")){
                        nrsd = checkUrlEncode(acdm, needReplaceString);
                        break;
                    }
                }
                if (str.length() >= oneDollarLength){
                    if (str.substring(lastDollarIndex, lastDollarIndex + oneDollarLength).equals("$urlDecode{")){
                        nrsd = checkUrlDecode(acdm, needReplaceString);
                        break;
                    }
                }
            }
            if (!nrsd.hasReplaced)
                break;

//            这里开始组装
//            String s1 = str.substring(0, lastDollarIndex);
//            String s2 = nrsd.string;
//            String s3 = str.substring(lastIndex + 1, str.length());
            str = str.substring(0, lastDollarIndex) + nrsd.string + str.substring(lastIndex + 1, str.length());

            if (str.contains("$")){
                findDollar = false; //这里假设已经没有没有$符号了
                for (String oneDollar:dollarList){
                    if (str.contains(oneDollar)){
                        findDollar = true;  //果然找到了美元符号
                        break;
                    }
                }
            }else {
                findDollar = false;
            }
        }

        nrsd.string = str;
        return nrsd;

    }

}
